home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
090
/
pctjmr86.arc
/
TJOS.ASM
< prev
Wrap
Assembly Source File
|
1985-12-13
|
5KB
|
223 lines
; File: tjos.asm
; Auth: Richard Foard
TITLE tjos
;
; Routines in this module (Microsoft C subroutine linkage):
;
;
; init_os()
;
; Prepares TJ/OS environment for use. Upon exit, caller is running
; as first task.
;
;
; int fork(stack, stack_size)
; char *stack;
; int stack_size;
;
; Creates and activates a task. Returns 'false' to the calling task and
; 'true' to the newly created task.
;
;
; yield()
;
; Allows a context switch to occur.
;
;
; wait(event_counter)
; int *event_counter;
;
; Waits for an event.
;
;
; post(event_counter)
; int *event_counter;
;
; Signals that an event has occurred.
;
;
; stop()
;
; Deactivates and destroys the calling task.
;
_TEXT SEGMENT BYTE PUBLIC 'CODE'
_TEXT ENDS
CONST SEGMENT WORD PUBLIC 'CONST'
CONST ENDS
_BSS SEGMENT WORD PUBLIC 'BSS'
_BSS ENDS
_DATA SEGMENT WORD PUBLIC 'DATA'
_DATA ENDS
DGROUP GROUP CONST, _BSS, _DATA
ASSUME CS: _TEXT, DS: DGROUP, SS: DGROUP, ES: DGROUP
PUBLIC _init_os
PUBLIC _yield
PUBLIC _fork
PUBLIC _wait
PUBLIC _post
PUBLIC _stop
PUBLIC __chkstk
_TEXT SEGMENT
EXTRN _exit:NEAR
_TEXT ENDS
_BSS SEGMENT
max_tasks equ 8
ct_limit equ max_tasks * 2
task_tbl dw max_tasks dup (0)
cur_task dw 0
actv_tasks dw 0
EVEN
_BSS ENDS
;---------------------------------------------------------------------------
_TEXT SEGMENT
;-------------------------
_init_os PROC NEAR ;init_os() {
mov cur_task,0 ; cur_task = 0;
mov actv_tasks,1 ; actv_tasks = 1;
sub ax,ax ; task_tbl[0..max_tasks - 1] = 0;
mov cx,max_tasks ;
mov bx,offset task_tbl ;
ini_1: ;
mov [bx],ax ;
add bx,2 ;
dec cx ;
jnz ini_1 ;
ret ;
_init_os ENDP ;}
;-------------------------
_yield PROC NEAR ;yield()
push bp ; (preserve BP)
mov bx,offset task_tbl ; task_tbl[cur_task] = SP;
mov ax,cur_task ;
add bx,ax ;
mov [bx],sp ;
yie_0: ;
add ax,2 ; do {
cmp ax,ct_limit ; cur_task = (cur_task + 2)
jne yie_1 ; % ct_limit;
sub ax,ax ;
yie_1: ;
mov bx,offset task_tbl ; } while (task_tbl[cur_task] == 0);
add bx,ax ;
push ax ;
mov ax,[bx] ;
or ax,ax ;
pop ax ;
jnz yie_2 ;
jmp yie_0 ;
yie_2: ;
mov bx,offset task_tbl ; SP = task_tbl[cur_task];
mov cur_task,ax ;
add bx,ax ;
mov sp,[bx] ;
pop bp ; (restore BP)
mov ax,1 ; return(1);
ret ;}
_yield ENDP
;-------------------------
_fork PROC NEAR ;int fork(stack, stack_size) {
mov ax,actv_tasks ; if (actv_tasks == max_tasks)
cmp ax,max_tasks ; exit(1);
jne for_0 ;
mov ax,1 ;
push ax ;
call _exit ;
for_0: ;
inc ax ; actv_tasks = actv_tasks + 1;
mov actv_tasks,ax ;
pop dx ; (caller's return addr)
pop ax ; (new task stack base)
pop bx ; (new task stack size)
push bx ; (restore caller's stack)
push ax ;
push dx ;
push bp ; (preserve caller's BP)
mov bp,sp ; (and caller's SP)
add ax,bx ; (establish new task's base sp)
sub ax,4 ; (allow pop of fork's parameters)
mov sp,ax ;
push dx ; (new task return addr)
push ax ; (and bp register image)
mov bx,offset task_tbl ; (find free slot in task_tbl)
for_1: mov ax,[bx] ;
or ax,ax ;
jz for_2 ;
add bx,2 ;
jmp for_1 ;
for_2: mov [bx],sp ; (install new task in task_tbl)
mov sp,bp ; (restore caller's stack)
pop bp ; (and BP)
sub ax,ax ; return (0);
ret ;}
_fork ENDP
;-------------------------
_wait PROC NEAR ;wait(event_counter) {
wai_0: pop cx ;
pop bx ;
push bx ;
push cx ;
cli ; (protect test-and-set)
mov ax,[bx] ;
or ax,ax ;
jnz wai_1 ; while (*event_counter == 0)
sti ;
call _yield ; yield();
jmp wai_0 ;
wai_1: dec ax ; --(*event_counter);
mov [bx],ax ;
sti ;
ret ;}
_wait ENDP ;
;-------------------------
_post PROC NEAR ;post(event_counter) {
pop cx ;
pop bx ;
push bx ;
inc word ptr [bx] ; ++(*event_counter);
jmp cx ;
_post ENDP ;}
;-------------------------
_stop PROC NEAR ;stop() {
mov ax,actv_tasks ; if (--actv_tasks == 0) exit(0);
dec ax ;
jnz sto_0 ;
sub ax,ax ;
push ax ;
call _exit ;
sto_0: ;
mov actv_tasks,ax ;
mov bx,offset task_tbl ;
mov ax,cur_task ;
add bx,ax ; task_tbl[cur_task] = 0;
mov word ptr [bx],0 ; (join 'yield' to switch context)
jmp yie_0 ;}
_stop ENDP
;-------------------------
__chkstk: ;chkstk:
pop cx ; (allocate AX bytes of stack space)
mov bx,sp ;
sub bx,ax ;
mov sp,bx ;
jmp cx ;
_TEXT ENDS
END